/**
 * 
 */
package com.abel.repository.impl;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.abel.datamodel.type.EducationInfo;
import com.abel.domain.Education;
import com.abel.domain.Person;
import com.abel.domain.PersonSearchCriteria;
import com.abel.repository.EducationRepository;
import com.abel.repository.exception.RepositoryException;
import com.abel.util.UserSessionLocator;


/**
 * @author admin
 *
 */
public class EducationRepositoryImpl  extends BaseRepositoryImpl implements EducationRepository {

    protected final Log logger = LogFactory.getLog(getClass());

    /* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#addEducation(com.abel.domain.Education)
	 */
	@Override
	public int addEducation(Education education) throws RepositoryException 
	{
	    logger.debug("@EducationRepositoryimpl : addEducation : entered");
	
	    Transaction tx = null;
		Session session = null;
		EducationInfo educationInfo = new EducationInfo();
		
		try {
			session = this.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			//add an education record
			Person person = UserSessionLocator.getUserSession().getPerson();
			educationInfo.setAplId(person.getApplication().getApplicationId());
			educationInfo.setEduType(education.getEduType());
			educationInfo.setEduSchoolName(education.getEduSchoolName());
	    	educationInfo.setEduSchoolCity(education.getEduSchoolCity());
	    	educationInfo.setEduSchoolState(education.getEduSchoolState());
	    	educationInfo.setEduGraduateYn(education.getEduGraduateYn());
	    	educationInfo.setEduGraduateYear(education.getEduGraduateYear());
	    	educationInfo.setEduGraduateMajor(education.getEduGraduateMajor());
	    	educationInfo.setEduDegree(education.getEduDegree());
	    	education.setEduCreateDts(new java.sql.Timestamp(System.currentTimeMillis()));
			educationInfo.setEduCreateDts(education.getEduCreateDts());

			//saving personal information
			int eduInfoId = Integer.parseInt(((Object)session.save(educationInfo)).toString());
			tx.commit();
			
			return eduInfoId;
	
	} 
	catch (RuntimeException e) {

		logger.info("@EducationRepositoryImpl : addRegistration : exception - exception while adding education for application id = " + education.getAplId());
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
			
				tx.rollback();
			
			} 
			catch (HibernateException he) {
				logger.debug("@EducationRepositoryImpl : addEducation : exception while rolling back education" + he);
				he.printStackTrace();
			}
		}
		throw new RepositoryException("Exception while adding education.",e);
	}

}


	/* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#updateEducation(com.abel.domain.Education)
	 */
	@Override
	public void updateEducation(Education education) throws RepositoryException {
	    logger.debug("@EducationRepositoryimpl : deleteEducation : entered");
		
	    Transaction tx = null;
		Session session = null;
		EducationInfo educationInfo = new EducationInfo();
		
		try {
			session = this.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			//update education record
			educationInfo.setEduInfoId(education.getEduInfoId());
			educationInfo.setAplId(education.getAplId());
			educationInfo.setEduType(education.getEduType());
			educationInfo.setEduSchoolName(education.getEduSchoolName());
	    	educationInfo.setEduSchoolCity(education.getEduSchoolCity());
	    	educationInfo.setEduSchoolState(education.getEduSchoolState());
	    	educationInfo.setEduGraduateYn(education.getEduGraduateYn());
	    	educationInfo.setEduGraduateYear(education.getEduGraduateYear());
	    	educationInfo.setEduGraduateMajor(education.getEduGraduateMajor());
	    	educationInfo.setEduDegree(education.getEduDegree());
	    	educationInfo.setEduCreateDts(education.getEduCreateDts());
	    	educationInfo.setEduLastUpdateDts(new java.sql.Timestamp(System.currentTimeMillis()));
	    	educationInfo.setEduLastUpdateId(UserSessionLocator.getUserSession().getAuthPrincipal().getUserName());
	    	
			//getting userId from UserSession
			int userId = UserSessionLocator.getUserSession().getAuthPrincipal().getUserId();
			if (userId <= 0) {
				throw new RepositoryException("Cannot update education information. UserId in authPrincipal is " + userId);
			}
	
			//updating education information
			session.update(educationInfo);
			tx.commit();
			
	} 
	catch (RuntimeException e) {
		
		logger.info("@ : addRegistration : exception while adding education for application id = " + education.getAplId());
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
					tx.rollback();
				} 
				catch (HibernateException he) {
					logger.debug("@EducationRepositoryImpl : updateEducation : exception while rolling back education" + he);
					he.printStackTrace();
				}
			}
			throw new RepositoryException("Exception while updating education.",e);
		}
	}

	/* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#deleteEducation(com.abel.domain.Education)
	 */
	@Override
	public void deleteEducation(int aplId, int eduInfoId) throws RepositoryException {
	    logger.debug("@EducationRepositoryimpl : deleteEducation : entered");
		
	    Transaction tx = null;
		Session session = null;
		EducationInfo educationInfo = new EducationInfo();
		
		try {
			session = this.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			//delete education record
			educationInfo.setEduInfoId(eduInfoId);
			educationInfo.setAplId(aplId);

			session.delete(educationInfo);
			tx.commit();
			
	} 
	catch (RuntimeException e) {
		//TODO check for duplicate key exception and throw it
		logger.info("@ : deleteRegistration : exception - delete failed for educations.edu_info_id= " + eduInfoId);
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
					tx.rollback();
				} 
				catch (HibernateException he) {
					logger.debug("@EducationRepositoryImpl : deleteEducation : exception while rolling back education" + he);
					he.printStackTrace();
				}
			}
			throw new RepositoryException("Exception while deleteing education.",e);
		}
	}

	/* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#deleteEducation(com.abel.domain.Education)
	 */
	@Override
	public void deleteEducation(int eduInfoId) throws RepositoryException {
	    logger.debug("@EducationRepositoryimpl : deleteEducation : entered");
		
	    Transaction tx = null;
		Session session = null;
		EducationInfo educationInfo = new EducationInfo();
		
		try {
			session = this.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			//delete education record
			educationInfo.setEduInfoId(eduInfoId);

			session.delete(educationInfo);
			tx.commit();
			
	} 
	catch (RuntimeException e) {
		
		logger.info("@ : deleteRegistration : exception - delete failed for educations.edu_info_id= " + eduInfoId);
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
					tx.rollback();
				} 
				catch (HibernateException he) {
					logger.debug("@EducationRepositoryImpl : deleteEducation : exception while rolling back education" + he);
					he.printStackTrace();
				}
			}
			throw new RepositoryException("Exception while deleteing education.",e);
		}
	}

	/* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#deleteEducation(com.abel.domain.Education)
	 */
	@Override
	public void deleteEducation(Education education) throws RepositoryException {
	    logger.debug("@EducationRepositoryimpl : deleteEducation : entered");
		
	    Transaction tx = null;
		Session session = null;
		EducationInfo educationInfo = new EducationInfo();
		
		try {
			session = this.getSessionFactory().getCurrentSession();
			tx = session.beginTransaction();
			
			//delete education record
			educationInfo.setEduInfoId(education.getEduInfoId());

			session.delete(educationInfo);
			tx.commit();
			
	} 
	catch (RuntimeException e) {
		//TODO check for duplicate key exception and throw it
		logger.info("@ : deleteRegistration : exception - delete failed for educations.edu_info_id= " + education.getEduInfoId());
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
					tx.rollback();
				} 
				catch (HibernateException he) {
					logger.debug("@EducationRepositoryImpl : deleteEducation : exception while rolling back education" + he);
					he.printStackTrace();
				}
			}
			throw new RepositoryException("Exception while deleteing education.",e);
		}
	}

	/* (non-Javadoc)
	 * @see com.abel.repository.EducationRepository#getEducationInformation(com.abel.domain.PersonSearchCriteria)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Education> getEducationInformation(PersonSearchCriteria criteria)
			throws RepositoryException {

	Transaction tx = null;
	Session session = null;

	try {
		session = this.getSessionFactory().getCurrentSession();
		tx = session.beginTransaction();
		
		List<Education> eduList = session.getNamedQuery("getEducationByUser").
		setParameter("userId", criteria.getUserId()).list();  // TODO how to get the apl_id - ask joseph to implement

		tx.commit();
		return eduList;
	} 
	catch (RuntimeException e) {
		
		e.printStackTrace();
		
		if (tx != null && tx.isActive()) {
		
			try {
			
				tx.rollback();
			
			}
			catch (HibernateException he) {
			
				logger.debug("@AuthRepositoryImpl : addRegistration : exception while rolling back registration" + he);
				he.printStackTrace();
			
			}
		}
		throw new RepositoryException("Excpetion while getting education for user Id=" + criteria.getUserId(),e);
	}
	}
}
